home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / T U R B O Language / Turbo C v2.0 / MCOMMAND.C < prev    next >
Text File  |  1988-08-29  |  19KB  |  830 lines

  1. /* Turbo C - (C) Copyright 1987, 1988 by Borland International */
  2.  
  3. #include <string.h>
  4. #include <mem.h>
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include <io.h>
  8. #include <fcntl.h>
  9. #include <conio.h>
  10. #include "mcalc.h"
  11.  
  12. char *name = MSGNAME;
  13.  
  14. void moverowup(void)
  15. /* Moves up 1 row */
  16. {
  17.  displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
  18.  if (currow > toprow)
  19.   currow--;
  20.  else if (toprow != 0)
  21.  {
  22.   scroll(DOWN, 1, LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  23.   displayrow(--toprow, NOUPDATE);
  24.   currow--;
  25.   setbottomrow();
  26.  }
  27. } /* moverowup */
  28.  
  29. void moverowdown(void)
  30. /* Moves down one row */
  31. {
  32.  displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
  33.  if (currow < bottomrow)
  34.   currow++;
  35.  else if (bottomrow < (MAXROWS - 1))
  36.  {
  37.   scroll(UP, 1, LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  38.   toprow++;
  39.   currow++;
  40.   setbottomrow();
  41.   displayrow(bottomrow, NOUPDATE);
  42.  }
  43. } /* moverowdown */
  44.  
  45. void movecolleft(void)
  46. /* Moves left one column */
  47. {
  48.  int col, oldleftcol;
  49.  unsigned char oldcolstart[SCREENCOLS];
  50.  
  51.  oldleftcol = leftcol;
  52.  movmem(colstart, oldcolstart, sizeof(colstart));
  53.  displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
  54.  if (curcol > leftcol)
  55.   curcol--;
  56.  else if (leftcol != 0)
  57.  {
  58.   curcol--;
  59.   leftcol--;
  60.   setrightcol();
  61.   setleftcol();
  62.   if (oldleftcol <= rightcol)
  63.    scroll(RIGHT, colstart[oldleftcol - leftcol] - LEFTMARGIN, LEFTMARGIN + 1,
  64.           3, 80, SCREENROWS + 2, WHITE);
  65.   clearlastcol();
  66.   for (col = leftcol; col <= oldleftcol - 1; col++)
  67.    displaycol(col, NOUPDATE);
  68.  }
  69. } /* movecolleft */
  70.  
  71. void movecolright(void)
  72. /* Moves right one column */
  73. {
  74.  int col, oldleftcol, oldrightcol;
  75.  unsigned char oldcolstart[SCREENCOLS];
  76.  
  77.  movmem(colstart, oldcolstart, sizeof(colstart));
  78.  oldleftcol = leftcol;
  79.  oldrightcol = rightcol;
  80.  displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
  81.  if (curcol < rightcol)
  82.   curcol++;
  83.  else if (rightcol < (MAXCOLS - 1))
  84.  {
  85.   curcol++;
  86.   rightcol++;
  87.   setleftcol();
  88.   setrightcol();
  89.   if (oldrightcol >= leftcol)
  90.    scroll(LEFT, oldcolstart[leftcol - oldleftcol] - LEFTMARGIN,
  91.           LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  92.   clearlastcol();
  93.   for (col = oldrightcol + 1; col <= rightcol; col++)
  94.    displaycol(col, NOUPDATE);
  95.  }
  96. } /* movecolright */
  97.  
  98. void recalc(void)
  99. /* Recalculates all of the numbers in the speadsheet */
  100. {
  101.  int col, row, dummy;
  102.  
  103.  for (col = 0; col <= lastcol; col++)
  104.  {
  105.   for (row = 0; row <= lastrow; row++)
  106.   {
  107.    if ((cell[col][row] != NULL) && (cell[col][row]->attrib == FORMULA))
  108.     cell[col][row]->v.f.fvalue = parse(cell[col][row]->v.f.formula, &dummy);
  109.   }
  110.  }
  111.  displayscreen(UPDATE);
  112. } /* recalc */
  113.  
  114. void changeautocalc(int newmode)
  115. /* Changes and prints the current AutoCalc value on the screen */
  116. {
  117.  char s[15];
  118.  
  119.  if (!autocalc && newmode)
  120.   recalc();
  121.  autocalc = newmode;
  122.  if (autocalc)
  123.   strcpy(s, MSGAUTOCALC);
  124.  else
  125.   s[0] = 0;
  126.  writef(73, 1, MSGAUTOCALCCOLOR, strlen(MSGAUTOCALC), s);
  127. } /* autocalc */
  128.  
  129. void changeformdisplay(int newmode)
  130. /* Changes and prints the current formula display value on the screen */
  131. {
  132.  char s[15];
  133.  
  134.  formdisplay = newmode;
  135.  if (formdisplay)
  136.   strcpy(s, MSGFORMDISPLAY);
  137.  else
  138.   s[0] = 0;
  139.  writef(65, 1, MSGFORMDISPLAYCOLOR, strlen(MSGFORMDISPLAY), s);
  140. } /* autocalc */
  141.  
  142. void editcell(CELLPTR ecell)
  143. /* Edits a selected cell */
  144. {
  145.  char s[MAXINPUT + 1];
  146.  
  147.  if (ecell == NULL)
  148.   return;
  149.  switch(ecell->attrib)
  150.  {
  151.   case TEXT :
  152.    strcpy(s, ecell->v.text);
  153.    break;
  154.   case VALUE :
  155.    if (ecell->v.value == HUGE_VAL)
  156.     strcpy(s, "0");
  157.    else
  158.     sprintf(s, "%.*f", MAXPLACES, ecell->v.value);
  159.    break;
  160.   case FORMULA :
  161.    strcpy(s, ecell->v.f.formula);
  162.    break;
  163.  } /* switch */
  164.  if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
  165.   return;
  166.  act(s);
  167.  changed = TRUE;
  168. } /* editcell */
  169.  
  170. void clearsheet(void)
  171. /* Clears the current spreadsheet */
  172. {
  173.  int col, row;
  174.  
  175.  for (row = 0; row <= lastrow; row++)
  176.  {
  177.   for (col = 0; col <= lastcol; col++)
  178.    deletecell(col, row, NOUPDATE);
  179.  }
  180.  initvars();
  181.  setrightcol();
  182.  setbottomrow();
  183.  displayscreen(NOUPDATE);
  184.  printfreemem();
  185.  changed = FALSE;
  186. } /* clearsheet */
  187.  
  188. struct CELLREC rec;
  189.  
  190. void loadsheet(char *filename)
  191. /* Loads a new spreadsheet */
  192. {
  193.  int size, allocated, reallastcol = 0, reallastrow = 0, file;
  194.  char check[81];
  195.  
  196.  if (filename[0] == 0)
  197.  {
  198.   writeprompt(MSGFILENAME);
  199.   if (!editstring(filename, "", MAXINPUT))
  200.    return;
  201.  }
  202.  if (access(filename, 0))
  203.  {
  204.   errormsg(MSGNOEXIST);
  205.   return;
  206.  }
  207.  if ((file = open(filename, O_RDWR | O_BINARY)) == -1)
  208.  {
  209.   errormsg(MSGNOOPEN);
  210.   return;
  211.  }
  212.  read(file, check, strlen(name) + 1);
  213.  if (strcmp(check, name) != 0)
  214.  {
  215.   errormsg(MSGNOMICROCALC);
  216.   close(file);
  217.   return;
  218.  }
  219.  writef(1, 25, PROMPTCOLOR, 79, MSGLOADING);
  220.  gotoxy(strlen(MSGLOADING) + 1, 25);
  221.  clearsheet();
  222.  read(file, (char *)&size, 1);
  223.  read(file, (char *)&lastcol, 2);
  224.  read(file, (char *)&lastrow, 2);
  225.  read(file, (char *)&size, 2);
  226.  read(file, colwidth, sizeof(colwidth));
  227.  do
  228.  {
  229.   if (read(file, (char *)&curcol, 2) <= 0)
  230.    break;
  231.   read(file, (char *)&currow, 2);
  232.   read(file, &format[curcol][currow], 1);
  233.   read(file, (char *)&size, 2);
  234.   read(file, (char *)&rec, size);
  235.   switch (rec.attrib)
  236.   {
  237.    case TEXT :
  238.     if ((allocated = alloctext(curcol, currow, rec.v.text)) == TRUE)
  239.      setoflags(curcol, currow, NOUPDATE);
  240.     break;
  241.    case VALUE :
  242.     allocated = allocvalue(curcol, currow, rec.v.value);
  243.     break;
  244.    case FORMULA :
  245.     allocated = allocformula(curcol, currow, rec.v.f.formula, rec.v.f.fvalue);
  246.     break;
  247.   } /* switch */
  248.   if (!allocated)
  249.   {
  250.    errormsg(MSGFILELOMEM);
  251.    lastrow = reallastrow;
  252.    lastcol = reallastcol;
  253.    format[curcol][currow] = DEFAULTFORMAT;
  254.    break;
  255.   }
  256.   else
  257.   {
  258.    if (curcol > reallastcol)
  259.     reallastcol = curcol;
  260.    if (currow > reallastrow)
  261.     reallastrow = currow;
  262.   }
  263.  }
  264.  while (TRUE);
  265.  writef(1, 25, WHITE, strlen(MSGLOADING), "");
  266.  gotoxy(1, 25);
  267.  printfreemem();
  268.  close(file);
  269.  curcol = currow = 0;
  270.  setrightcol();
  271.  displayscreen(NOUPDATE);
  272.  changed = FALSE;
  273. } /* loadsheet */
  274.  
  275. void savesheet(void)
  276. /* Saves the current spreadsheet */
  277. {
  278.  char filename[MAXINPUT+1], eof = 26;
  279.  int size, col, row, overwrite, file;
  280.  CELLPTR cellptr;
  281.  
  282.  filename[0] = 0;
  283.  writeprompt(MSGFILENAME);
  284.  if (!editstring(filename, "", MAXINPUT))
  285.   return;
  286.  if (!access(filename, 0))
  287.  {
  288.   if (!getyesno(&overwrite, MSGOVERWRITE) || (overwrite == 'N'))
  289.    return;
  290.  }
  291.  if ((file = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
  292.   S_IREAD | S_IWRITE)) == -1)
  293.  {
  294.   errormsg(MSGNOOPEN);
  295.   return;
  296.  }
  297.  writef(1, 25, PROMPTCOLOR, 79, MSGSAVING);
  298.  gotoxy(strlen(MSGSAVING) + 1, 25);
  299.  write(file, name, strlen(name) + 1);
  300.  write(file, &eof, 1);
  301.  write(file, (char *)&lastcol, 2);
  302.  write(file, (char *)&lastrow, 2);
  303.  size = MAXCOLS;
  304.  write(file, (char *)&size, 2);
  305.  write(file, colwidth, sizeof(colwidth));
  306.  for (row = 0; row <= lastrow; row++)
  307.  {
  308.   for (col = lastcol; col >= 0; col--)
  309.   {
  310.    if (cell[col][row] != NULL)
  311.    {
  312.     cellptr = cell[col][row];
  313.     switch(cellptr->attrib)
  314.     {
  315.      case TEXT :
  316.       size = strlen(cellptr->v.text) + 2;
  317.       break;
  318.      case VALUE :
  319.       size = sizeof(double) + 1;
  320.       break;
  321.      case FORMULA :
  322.       size = strlen(cellptr->v.f.formula) + 2 + sizeof(double);
  323.       break;
  324.     } /* switch */
  325.     write(file, (char *)&col, 2);
  326.     write(file, (char *)&row, 2);
  327.     write(file, (char *)&format[col][row], 1);
  328.     write(file, (char *)&size, 2);
  329.     write(file, (char *)cellptr, size);
  330.    }
  331.   }
  332.  }
  333.  close(file);
  334.  writef(1, 25, WHITE, strlen(MSGSAVING), "");
  335.  gotoxy(1, 25);
  336.  changed = FALSE;
  337. } /* savesheet */
  338.  
  339. int pagerows(int row, int toppage, int border)
  340. /* Returns the number of rows to print */
  341. {
  342.  int rows;
  343.  
  344.  rows = toppage ? 66 - TOPMARGIN : 66;
  345.  if (border)
  346.   rows--;
  347.  if (row + rows - 1 > lastrow)
  348.   return(lastrow - row + 1);
  349.  else
  350.   return(rows);
  351. } /* pagerows */
  352.  
  353. int pagecols(int col, int border, int columns)
  354. /* Returns the number of columns to print starting at col */
  355. {
  356.  int len = ((col == 0) && (border)) ? columns - LEFTMARGIN : columns;
  357.  int firstcol = col;
  358.  
  359.  while ((len > 0) && (col <= lastcol))
  360.   len -= colwidth[col++];
  361.  if (len < 0)
  362.   col--;
  363.  return(col - firstcol);
  364. } /* pagecols */
  365.  
  366. void printsheet(void)
  367. /* Prints a copy of the spreadsheet to a file or to the printer */
  368. {
  369.  char filename[MAXINPUT + 1], s[133], colstr[MAXCOLWIDTH + 1];
  370.  FILE *file;
  371.  int columns, counter1, counter2, counter3, col = 0, row, border, toppage,
  372.   lcol, lrow, dummy, printed, oldlastcol;
  373.  
  374.  filename[0] = 0;
  375.  writeprompt(MSGPRINT);
  376.  if (!editstring(filename, "", MAXINPUT))
  377.   return;
  378.  if (filename[0] == 0)
  379.   strcpy(filename, "PRN");
  380.  if ((file = fopen(filename, "wt")) == NULL)
  381.  {
  382.   errormsg(MSGNOOPEN);
  383.   return;
  384.  }
  385.  oldlastcol = lastcol;
  386.  for (counter1 = 0; counter1 <= lastrow; counter1++)
  387.  {
  388.   for (counter2 = lastcol; counter2 < MAXCOLS; counter2++)
  389.   {
  390.    if (format[counter2][counter1] >= OVERWRITE)
  391.     lastcol = counter2;
  392.   }
  393.  }
  394.  if (!getyesno(&columns, MSGCOLUMNS))
  395.   return;
  396.  columns = (columns == 'Y') ? 131 : 79;
  397.  if (!getyesno(&border, MSGBORDER))
  398.   return;
  399.  border = (border == 'Y');
  400.  while (col <= lastcol)
  401.  {
  402.   row = 0;
  403.   toppage = TRUE;
  404.   lcol = pagecols(col, border, columns) + col;
  405.   while (row <= lastrow)
  406.   {
  407.    lrow = pagerows(row, toppage, border) + row;
  408.    printed = 0;
  409.    if (toppage)
  410.    {
  411.     for (counter1 = 0; counter1 < TOPMARGIN; counter1++)
  412.     {
  413.      fprintf(file, "\n");
  414.      printed++;
  415.     }
  416.    }
  417.    for (counter1 = row; counter1 < lrow; counter1++)
  418.    {
  419.     if ((border) && (counter1 == row) && (toppage))
  420.     {
  421.      if ((col == 0) && (border))
  422.       sprintf(s, "%*s", LEFTMARGIN, "");
  423.      else
  424.       s[0] = 0;
  425.      for (counter3 = col; counter3 < lcol; counter3++)
  426.      {
  427.       centercolstring(counter3, colstr);
  428.       strcat(s, colstr);
  429.      }
  430.      fprintf(file, "%s\n", s);
  431.      printed++;
  432.     }
  433.     if ((col == 0) && (border))
  434.      sprintf(s, "%-*d", LEFTMARGIN, counter1 + 1);
  435.     else
  436.      s[0] = 0;
  437.     for (counter2 = col; counter2 < lcol; counter2++)
  438.      strcat(s, cellstring(counter2, counter1, &dummy, FORMAT));
  439.     fprintf(file, "%s\n", s);
  440.     printed++;
  441.    }
  442.    row = lrow;
  443.    toppage = FALSE;
  444.    if (printed < 66)
  445.     fprintf(file, "%c", FORMFEED);
  446.   }
  447.   col = lcol;
  448.  }
  449.  fclose(file);
  450.  lastcol = oldlastcol;
  451. } /* printsheet */
  452.  
  453. void setcolwidth(int col)
  454. /* Sets the new column width for a selected column */
  455. {
  456.  int width, row;
  457.  
  458.  writeprompt(MSGCOLWIDTH);
  459.  if (!getint(&width, MINCOLWIDTH, MAXCOLWIDTH))
  460.   return;
  461.  colwidth[col] = width;
  462.  setrightcol();
  463.  if (rightcol < col)
  464.  {
  465.   rightcol = col;
  466.   setleftcol();
  467.   setrightcol();
  468.  }
  469.  for (row = 0; row <= lastrow; row++)
  470.  {
  471.   if ((cell[col][row] != NULL) && (cell[col][row]->attrib == TEXT))
  472.    clearoflags(col + 1, row, NOUPDATE);
  473.   else
  474.    clearoflags(col, row, NOUPDATE);
  475.   updateoflags(col, row, NOUPDATE);
  476.  }
  477.  displayscreen(NOUPDATE);
  478.  changed = TRUE;
  479. } /* setcolwidth */
  480.  
  481. void gotocell()
  482. /* Moves to a selected cell */
  483. {
  484.  writeprompt(MSGGOTO);
  485.  if (!getcell(&curcol, &currow))
  486.   return;
  487.  leftcol = curcol;
  488.  toprow = currow;
  489.  setbottomrow();
  490.  setrightcol();
  491.  setleftcol();
  492.  displayscreen(NOUPDATE);
  493. } /* gotocell */
  494.  
  495. void formatcells(void)
  496. /* Prompts the user for a selected format and range of cells */
  497. {
  498.  int col, row, col1, col2, row1, row2, temp, newformat = 0;
  499.  
  500.  writeprompt(MSGCELL1);
  501.  if (!getcell(&col1, &row1))
  502.   return;
  503.  writeprompt(MSGCELL2);
  504.  if (!getcell(&col2, &row2))
  505.   return;
  506.  if ((col1 != col2) && (row1 != row2))
  507.   errormsg(MSGDIFFCOLROW);
  508.  else
  509.  {
  510.   if (col1 > col2)
  511.    swap(&col1, &col2);
  512.   if (row1 > row2)
  513.    swap(&row1, &row2);
  514.   if (!getyesno(&temp, MSGRIGHTJUST))
  515.    return;
  516.   newformat += (temp == 'Y') * RJUSTIFY;
  517.   if (!getyesno(&temp, MSGDOLLAR))
  518.    return;
  519.   newformat += (temp == 'Y') * DOLLAR;
  520.   if (!getyesno(&temp, MSGCOMMAS))
  521.    return;
  522.   newformat += (temp == 'Y') * COMMAS;
  523.   if (newformat & DOLLAR)
  524.    newformat += 2;
  525.   else
  526.   {
  527.    writeprompt(MSGPLACES);
  528.    if (!getint(&temp, 0, MAXPLACES))
  529.     return;
  530.    newformat += temp;
  531.   }
  532.   for (col = col1; col <= col2; col++)
  533.   {
  534.    for (row = row1; row <= row2; row++)
  535.    {
  536.     format[col][row] = (format[col][row] & OVERWRITE) | newformat;
  537.     if ((col >= leftcol) && (col <= rightcol) &&
  538.      (row >= toprow) && (row <= bottomrow))
  539.      displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
  540.    }
  541.   }
  542.  }
  543.  changed = TRUE;
  544. } /* formatcells */
  545.  
  546. void deletecol(int col)
  547. /* Deletes a column */
  548. {
  549.  int counter, row;
  550.  
  551.  for (counter = 0; counter <= lastrow; counter++)
  552.   deletecell(col, counter, NOUPDATE);
  553.  printfreemem();
  554.  if (col != MAXCOLS - 1)
  555.  {
  556.   movmem(&cell[col + 1][0], &cell[col][0], MAXROWS * sizeof(CELLPTR) *
  557.    (MAXCOLS - col - 1));
  558.   movmem(&format[col + 1][0], &format[col][0], MAXROWS * (MAXCOLS - col - 1));
  559.   movmem(&colwidth[col + 1], &colwidth[col], MAXCOLS - col - 1);
  560.  }
  561.  setmem(&cell[MAXCOLS - 1][0], MAXROWS * sizeof(CELLPTR), 0);
  562.  setmem(&format[MAXCOLS - 1][0], MAXROWS, DEFAULTFORMAT);
  563.  colwidth[MAXCOLS - 1] = DEFAULTWIDTH;
  564.  if ((lastcol >= col) && (lastcol > 0))
  565.   lastcol--;
  566.  setrightcol();
  567.  if (curcol > rightcol)
  568.  {
  569.   rightcol++;
  570.   setleftcol();
  571.  }
  572.  clearlastcol();
  573.  for (counter = 0; counter <= lastcol; counter++)
  574.  {
  575.   for (row = 0; row <= lastrow; row++)
  576.   {
  577.    if ((cell[counter][row] != NULL) &&
  578.     (cell[counter][row]->attrib == FORMULA))
  579.     fixformula(counter, row, COLDEL, col);
  580.    updateoflags(col, row, NOUPDATE);
  581.   }
  582.  }
  583.  while (col <= rightcol)
  584.   displaycol(col++, NOUPDATE);
  585.  changed = TRUE;
  586.  recalc();
  587. } /* deletecol */
  588.  
  589. void insertcol(int col)
  590. /* Inserts a column */
  591. {
  592.  int counter, row;
  593.  
  594.  if (lastcol == MAXCOLS - 1)
  595.  {
  596.   for (counter = 0; counter <= lastrow; counter++)
  597.    deletecell(lastcol, counter, NOUPDATE);
  598.   printfreemem();
  599.  }
  600.  if (col != MAXCOLS - 1)
  601.  {
  602.   movmem(&cell[col][0], &cell[col + 1][0], MAXROWS * sizeof(CELLPTR) *
  603.    (MAXCOLS - col - 1));
  604.   movmem(&format[col][0], &format[col + 1][0], MAXROWS * (MAXCOLS - col - 1));
  605.   movmem(&colwidth[col], &colwidth[col + 1], MAXCOLS - col - 1);
  606.  }
  607.  setmem(&cell[col][0], MAXROWS * sizeof(CELLPTR), 0);
  608.  setmem(&format[col][0], MAXROWS, DEFAULTFORMAT);
  609.  colwidth[col] = DEFAULTWIDTH;
  610.  lastcol = MAXCOLS - 1;
  611.  setlastcol();
  612.  setrightcol();
  613.  if (curcol > rightcol)
  614.  {
  615.   rightcol++;
  616.   setleftcol();
  617.  }
  618.  for (counter = 0; counter <= lastcol; counter++)
  619.  {
  620.   for (row = 0; row <= lastrow; row++)
  621.   {
  622.    if ((cell[counter][row] != NULL) &&
  623.     (cell[counter][row]->attrib == FORMULA))
  624.     fixformula(counter, row, COLADD, col);
  625.    updateoflags(col, row, NOUPDATE);
  626.   }
  627.  }
  628.  while (col <= rightcol)
  629.   displaycol(col++, NOUPDATE);
  630.  changed = TRUE;
  631.  recalc();
  632. } /* insertcol */
  633.  
  634. void deleterow(int row)
  635. /* Deletes a row */
  636. {
  637.  int counter, rowc;
  638.  
  639.  for (counter = 0; counter <= lastcol; counter++)
  640.   deletecell(counter, row, NOUPDATE);
  641.  printfreemem();
  642.  if (row != MAXROWS - 1)
  643.  {
  644.   for (counter = 0; counter < MAXCOLS; counter++)
  645.   {
  646.    movmem(&cell[counter][row + 1], &cell[counter][row],
  647.     sizeof(CELLPTR) * (MAXROWS - row - 1));
  648.    movmem(&format[counter][row + 1], &format[counter][row], MAXROWS - row - 1);
  649.   }
  650.  }
  651.  else
  652.  {
  653.   for (counter = 0; counter <= lastcol; counter++)
  654.   {
  655.    cell[counter][MAXROWS - 1] = NULL;
  656.    format[counter][MAXROWS - 1] = DEFAULTFORMAT;
  657.   }
  658.  }
  659.  if ((lastrow >= row) && (lastrow > 0))
  660.   lastrow--;
  661.  for (counter = 0; counter <= lastcol; counter++)
  662.  {
  663.   for (rowc = 0; rowc <= lastrow; rowc++)
  664.   {
  665.    if ((cell[counter][rowc] != NULL) &&
  666.     (cell[counter][rowc]->attrib == FORMULA))
  667.     fixformula(counter, rowc, ROWDEL, row);
  668.   }
  669.  }
  670.  while (row <= bottomrow)
  671.   displayrow(row++, NOUPDATE);
  672.  changed = TRUE;
  673.  recalc();
  674. } /* deleterow */
  675.  
  676. void insertrow(int row)
  677. /* Inserts a row */
  678. {
  679.  int counter, rowc;
  680.  
  681.  if (lastrow == MAXROWS - 1)
  682.  {
  683.   for (counter = 0; counter <= lastcol; counter++)
  684.    deletecell(counter, lastrow, NOUPDATE);
  685.   printfreemem();
  686.  }
  687.  if (row != MAXROWS - 1)
  688.  {
  689.   for (counter = 0; counter < MAXCOLS; counter++)
  690.   {
  691.    movmem(&cell[counter][row], &cell[counter][row + 1],
  692.     sizeof(CELLPTR) * (MAXROWS - row - 1));
  693.    movmem(&format[counter][row], &format[counter][row + 1], MAXROWS - row - 1);
  694.   }
  695.  }
  696.  for (counter = 0; counter < MAXCOLS; counter++)
  697.  {
  698.   cell[counter][row] = NULL;
  699.   format[counter][row] = DEFAULTFORMAT;
  700.  }
  701.  lastrow = MAXROWS - 1;
  702.  setlastrow();
  703.  for (counter = 0; counter <= lastcol; counter++)
  704.  {
  705.   for (rowc = 0; rowc <= lastrow; rowc++)
  706.   {
  707.    if ((cell[counter][rowc] != NULL) &&
  708.     (cell[counter][rowc]->attrib == FORMULA))
  709.     fixformula(counter, rowc, ROWADD, row);
  710.   }
  711.  }
  712.  while (row <= bottomrow)
  713.   displayrow(row++, NOUPDATE);
  714.  changed = TRUE;
  715.  recalc();
  716. } /* insertrow */
  717.  
  718. void smenu(void)
  719. /* Executes the commands in the spreadsheet menu */
  720. {
  721.  char filename[MAXINPUT + 1];
  722.  
  723.  filename[0] = 0;
  724.  switch(getcommand(SMENU, SCOMMAND))
  725.  {
  726.   case 0 :
  727.    checkforsave();
  728.    loadsheet(filename);
  729.    break;
  730.   case 1 :
  731.    savesheet();
  732.    break;
  733.   case 2 :
  734.    printsheet();
  735.    break;
  736.   case 3 :
  737.    checkforsave();
  738.    clearsheet();
  739.    break;
  740.  } /* switch */
  741. } /* smenu */
  742.  
  743. void cmenu(void)
  744. /* Executes the commands in the column menu */
  745. {
  746.  switch(getcommand(CMENU, CCOMMAND))
  747.  {
  748.   case 0 :
  749.    insertcol(curcol);
  750.    break;
  751.   case 1 :
  752.    deletecol(curcol);
  753.    break;
  754.   case 2 :
  755.    setcolwidth(curcol);
  756.    break;
  757.  } /* switch */
  758. } /* cmenu */
  759.  
  760. void rmenu(void)
  761. /* Executes the commands in the row menu */
  762. {
  763.  switch(getcommand(RMENU, RCOMMAND))
  764.  {
  765.   case 0 :
  766.    insertrow(currow);
  767.    break;
  768.   case 1 :
  769.    deleterow(currow);
  770.    break;
  771.  } /* switch */
  772. } /* rmenu */
  773.  
  774. void umenu(void)
  775. /* Executes the commands in the utility menu */
  776. {
  777.  switch(getcommand(UMENU, UCOMMAND))
  778.  {
  779.   case 0 :
  780.    recalc();
  781.    break;
  782.   case 1 :
  783.    changeformdisplay(!formdisplay);
  784.    displayscreen(UPDATE);
  785.    break;
  786.  } /* switch */
  787. } /* umenu */
  788.  
  789. void mainmenu(void)
  790. /* Executes the commands in the main menu */
  791. {
  792.  switch(getcommand(MENU, COMMAND))
  793.  {
  794.   case 0 :
  795.    smenu();
  796.    break;
  797.   case 1 :
  798.    formatcells();
  799.    break;
  800.   case 2 :
  801.    deletecell(curcol, currow, UPDATE);
  802.    printfreemem();
  803.    if (autocalc)
  804.     recalc();
  805.    break;
  806.   case 3 :
  807.    gotocell();
  808.    break;
  809.   case 4 :
  810.    cmenu();
  811.    break;
  812.   case 5 :
  813.    rmenu();
  814.    break;
  815.   case 6 :
  816.    editcell(curcell);
  817.    break;
  818.   case 7 :
  819.    umenu();
  820.    break;
  821.   case 8 :
  822.    changeautocalc(!autocalc);
  823.    break;
  824.   case 9 :
  825.    checkforsave();
  826.    stop = TRUE;
  827.    break;
  828.  } /* switch */
  829. } /* mainmenu */
  830.